﻿using System;
using System.ComponentModel.Composition.Hosting;
using OperationPlugins.Compositions;

namespace OperationPlugins
{
    public static class OperationPluginsEnvironment
    {
        #region Fields

        private static bool _initializing;
        private static bool _initialized;

        #endregion

        /// <summary>
        /// Checks if the framework has already been initialized.
        /// </summary>
        public static bool IsInitialized { get { return _initialized; } }

        /// <summary>
        /// Checks if the framework is currently initializing.
        /// </summary>
        public static bool IsInitializing { get { return _initializing; } }

        /// <summary>
        /// Checks the initialization status, for internal use only!
        /// </summary>
        internal static void CheckStatus()
        {
            if (IsInitialized == false)
            {
                throw new OperationPluginsEnvironmentException("The OperationPluginsEnvironment has not been initialized.");                
            }
        }

        /// <summary>
        /// Initializes the framework.
        /// </summary>
        /// <remarks>
        /// This method can only be called once and should be called on the application start-up!
        /// </remarks>
        public static void Initialize()
        {
            if (IsInitializing || IsInitialized)
            {
                throw new OperationPluginsEnvironmentException("The OperationPluginsEnvironment has already been initialized or is currently being initialized.");
            }

            _initializing = true;

            // Create the composition container.
            CompositionContainer container = CompositionContainerFactory.CreateCompositionContainer();

            // Create a new initialization context.
            var context = new InitializationContext();
            context.CompositionContainer = container;

            // Initialize compositions by using the IInitializable interface.
            foreach (var plugin in container.GetPlugins<IInitializable>())
            {
                plugin.Initialize(context);
            }

            _initialized = true;
            _initializing = false;
        }

        public sealed class OperationPluginsEnvironmentException : Exception
        {
            public OperationPluginsEnvironmentException(string message)
                : base(message)
            {
            }
        }

    }
}